package cn.dada.dadarecipes.community.audit.service.impl;

import cn.dada.dadarecipes.base.enums.ArticleAuditStatusEnum;
import cn.dada.dadarecipes.base.exception.ServiceException;
import cn.dada.dadarecipes.base.response.StatusCode;
import cn.dada.dadarecipes.community.article.mapper.ArticleMapper;
import cn.dada.dadarecipes.community.article.pojo.entity.Article;
import cn.dada.dadarecipes.community.audit.mapper.AuditMapper;
import cn.dada.dadarecipes.community.audit.pojo.dto.AuditParam;
import cn.dada.dadarecipes.community.audit.pojo.dto.AuditQuery;
import cn.dada.dadarecipes.community.audit.pojo.entity.Audit;
import cn.dada.dadarecipes.community.audit.pojo.vo.AuditVO;
import cn.dada.dadarecipes.community.audit.service.AuditService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
@Transactional
public class AuditServiceImpl implements AuditService {
    @Autowired
    private AuditMapper auditMapper;
    @Autowired
    private ArticleMapper articleMapper;

    /**
     * 业务层-文章审核列表查询
     * @param auditQuery
     * @return List<AuditVO>
     */
    @Override
    public List<AuditVO> selectAudit(AuditQuery auditQuery) {
        log.debug("业务层-文章审核列表查询:{}", auditQuery);
        List<AuditVO> list = auditMapper.selectAudit(auditQuery);
        if (list.isEmpty()) throw new ServiceException(StatusCode.AUDIT_NOT_EXIST);
        return list;
    }



    /**
     * 业务层-文章审核状态更新
     * @param auditParam
     */
    @Override
    public void updateAuditStatus(AuditParam auditParam) {
        log.debug("业务层-文章审核状态更新: {}",auditParam);
        Audit audit = new Audit();
        BeanUtils.copyProperties(auditParam, audit);

        /* 文章审核状态合法性校验 */
        String oldStatus = auditStatusValidation(audit);

        /* 判断驳回理由非空校验 */
        String status = audit.getAuditStatus();
        String reason = audit.getReason();
        articleRejectReasonValidation(status, reason, audit);

        /* 更新审核表审核状态 */
        Boolean isSuccess;
        LocalDateTime now = LocalDateTime.now();
        //当状态为审核通过，设置通过时间
        if (status.equals(ArticleAuditStatusEnum.AUDIT_PASS.getCode())){
            audit.setPassTime(now);
        }
        audit.setUpdateTime(now);//更新时间
        isSuccess = auditMapper.updateAuditStatus(audit);
        // 判断状态是否更新成功
        if (!isSuccess) throw new ServiceException(StatusCode.OPERATION_FAILED);

        /* 更新文章审核状态 */
        Article article = new Article();
        article.setId(audit.getArticleId());//文章id
        article.setAuditStatus(audit.getAuditStatus());//审核状态
        article.setUpdateTime(now);//更新时间
        isSuccess = articleMapper.updateArticleStatus(article);
        //状态更新失败，回滚审核单审核状态
//        if (!isSuccess){
//            audit.setReason(null);//原因回滚
//            audit.setPassTime(null);//通过时间回滚
//            audit.setAuditStatus(oldStatus);//状态回滚
//            audit.setUpdateTime(now);//更新时间回滚
//            auditMapper.updateAuditStatus(audit);
//            throw new ServiceException(StatusCode.OPERATION_FAILED);
//        }
    }
    /**
     * 文章审核状态合法性校验
     * @param audit
     * @return 数据库中原审核单审核状态
     */
    private String auditStatusValidation(Audit audit) {
        /* 查询文章原有审核状态 */
        AuditQuery auditQuery = new AuditQuery();
        auditQuery.setId(audit.getId());
        List<AuditVO> auditVOS = auditMapper.selectAudit(auditQuery);
        if (auditVOS.isEmpty()) throw new ServiceException(StatusCode.AUDIT_NOT_EXIST);//审核表不存在

        /* 审核状态合法性验证 */
        String oldStatus = auditVOS.get(0).getAuditStatus();
        if (oldStatus.equals(ArticleAuditStatusEnum.AUDIT_PASS.getCode())){
            throw new ServiceException(StatusCode.AUDIT_ALREADY_PASS);//审核已经通过
        }
        if (oldStatus.equals(ArticleAuditStatusEnum.REJECT.getCode())){
            throw new ServiceException(StatusCode.ARTICLE_ALREADY_REJECT);//审核已经驳回
        }
        return oldStatus;
    }
    /**
     * 判断驳回理由非空校验
     * @param status 驳回状态
     * @param reason 驳回理由
     * @param audit
     */
    private void articleRejectReasonValidation(String status, String reason, Audit audit) {
        if (status.equals(ArticleAuditStatusEnum.REJECT.getCode())) {
            if (reason == null || reason.trim().isEmpty()) {//驳回理由为空
                throw new ServiceException(StatusCode.ARTICLE_REASON_NOT_EMPTY);//驳回理由不能为空
            }
        }else {
            //当不为驳回状态时驳回理由存在时，为防止写入设置为null值
            audit.setReason(null);
        }
    }
}
